package com.wo.cloud.filter;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.wo.cloud.security.TokenManager;
import com.wo.cloud.util.Response;
import com.wo.cloud.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author liry
 * @version 1.0
 * @date Created on 2021/4/19 9:44
 * Description: 授权过滤器类
 */
public class TokenAuthFilter extends BasicAuthenticationFilter {

    private RedisTemplate<String, Object> redisTemplate;
    private TokenManager tokenManager;


    @Autowired
    public TokenAuthFilter(AuthenticationManager authenticationManager,
                           RedisTemplate redisTemplate,
                           TokenManager tokenManager) {
        super(authenticationManager);
        this.redisTemplate = redisTemplate;
        this.tokenManager = tokenManager;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            // 取token, 解析认证信息
            UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);

            if (ObjectUtil.isNotNull(authenticationToken)) {
                // 将信息放到权限上下文中
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }

            chain.doFilter(request, response);
        }catch (Exception e){
            ResponseUtil.out(response, Response.fail("授权失败，请校验token是否正确"));
        }
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StrUtil.isNotBlank(token)) {
            // 获取用户名
            String userInfoByToken = tokenManager.getUserInfoByToken(token);

            // 对比redis token,获取认证权限信息
            List<SimpleGrantedAuthority> auths = (List<SimpleGrantedAuthority>) redisTemplate.opsForValue().get(userInfoByToken);

            // String 封装成 SimpleGrantedAuthority 对象
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            assert auths != null;
            for (SimpleGrantedAuthority auth : auths) {
//                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(auth);
                authorities.add(auth);
            }
            return new UsernamePasswordAuthenticationToken(userInfoByToken, token, authorities);
        }
        return null;
    }
}
